import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQml.Models 2.15
import QtQuick.Layouts 1.15

import org.ukui.systemTray 1.0
import org.ukui.quick.items 1.0 as UkuiItems
import org.ukui.quick.platform 1.0 as Platform

DropArea {
    property real scaleFactor
    property real itemWidth
    property real itemHeight
    property real itemLong
    property real itemShort
    property bool itemOrientation: true
    property int panelPos
    property int dragType
    property bool inserted: false
    property int targetIndex
    property int indexInFold
    property bool isOverLength: false
    property bool callMenu: false

    height: parent.panelOrientation ? parent.height : flowArea.height
    width: parent.panelOrientation ? flowArea.width : parent.width

    onItemShortChanged: {
        trayview.viewWidth = trayModel.count * dropArea.itemShort + (trayModel.count - 1) * trayview.viewSpacing;
    }

    Flow {
        id: flowArea
        anchors.verticalCenter: parent.verticalCenter
        anchors.horizontalCenter: parent.horizontalCenter
        flow: dropArea.itemOrientation ? GridLayout.LeftToRight : GridLayout.TopToBottom
        spacing: 0

        DropArea {
            width: dropArea.itemWidth
            height: dropArea.itemHeight

            onEntered: {
            }
            onDropped: {
                if (drag.source.rootId !== dropArea) return;
                if (dragType === 1) {
                    if (trayModel.count > 11) return;
                    ItemModel.setOrderInGroup(FoldModel, FoldModel.index(foldBase.sourceIndex,0), 0)
                    ItemModel.changeSeparateIndex(true);
                }
                if (dragType === 0) {
                    ItemModel.setOrderInGroup(ShowModel, ShowModel.index(trayview.sourceIndex, 0), trayModel.items.count - 1);
                    ItemModel.changeSeparateIndex(false);
                }
            }

            UkuiItems.StyleBackground {
                id: foldItem
                visible: !foldBase.isEmpty
                clip: true
                useStyleTransparency: false
                anchors.fill: parent
                paletteRole: Platform.Theme.BrightText
                alpha: foldControl.containsPress ? 0.1 : foldControl.isContain ? 0.05 : 0
                radius: Platform.Theme.maxRadius

                TrayIcon {
                    id: foldControl
                    property bool isContain: false
                    width: dropArea.itemWidth
                    height: dropArea.itemHeight
                    appIcon: ShowModel.foldIcon()
                    iconRotation: appIconRotation()
                    hoverEnabled: true
                    acceptedButtons: Qt.LeftButton | Qt.RightButton

                    onEntered: {
                        isContain = true;
                    }
                    onExited: {
                        isContain = false
                    }
                    onCanceled: {
                        isContain = false
                    }

                    onClicked: {
                        if (mouse.button === Qt.LeftButton) {
                            foldWindowReply();
                        }
                    }

                    function appIconRotation() {
                        if (dropArea.panelPos === UkuiItems.Types.Left) {
                            return trayview.isFold ? 180 : 0;
                        } else if (dropArea.panelPos === UkuiItems.Types.Top) {
                            return trayview.isFold ? 270 : 90;
                        } else if (dropArea.panelPos === UkuiItems.Types.Right) {
                            return trayview.isFold ? 0 : 180;
                        } else if (dropArea.panelPos === UkuiItems.Types.Bottom) {
                            return trayview.isFold ? 90 : 270;
                        }
                        return 0;
                    }

                    function foldWindowReply() {
                        if (trayview.isFold) {
                            foldWindow.hide();
                            trayview.isFold = false;
                        } else {
                            if (!foldBase.isEmpty) {
                                updateFoldWindowPosition();
                                foldWindow.show();
                            }
                            trayview.isFold = true;
                        }
                    }

                    function updateFoldWindowPosition() {
                        if (dropArea.panelPos === UkuiItems.Types.Left) {
                            foldWindow.location = UkuiItems.Types.LeftEdge
                        } else if (dropArea.panelPos === UkuiItems.Types.Top) {
                            foldWindow.location = UkuiItems.Types.TopEdge
                        } else if (dropArea.panelPos === UkuiItems.Types.Right) {
                            foldWindow.location = UkuiItems.Types.RightEdge
                        } else if (dropArea.panelPos === UkuiItems.Types.Bottom) {
                            foldWindow.location = UkuiItems.Types.BottomEdge
                        }
                        foldWindow.margin = 10;
                    }
                }


                UkuiItems.Dialog {
                    id: foldWindow
                    visualParent: foldItem
                    mainItem: foldBase
                    enableWindowBlur: true
                    type: Platform.WindowType.Normal

                    minimumWidth: foldBase.width
                    maximumWidth: minimumWidth
                    minimumHeight: foldBase.height
                    maximumHeight: minimumHeight

                    FoldArea {
                        id: foldBase
                        onFoldAreaDragFinshed: fromIndex => {
                                                   if (dropArea.inserted) {
                                                       if (dropArea.dragType === 1) {
                                                           dropArea.inserted = false;
                                                           if (trayview.itemAtIndex(dropArea.targetIndex).isFixed) return;
                                                           trayModel.items.remove(dropArea.targetIndex);
                                                           ItemModel.setOrderBetweenGroups(FoldModel,
                                                                                           FoldModel.index(dropArea.isOverLength ? fromIndex + 1 : fromIndex, 0),
                                                                                           ShowModel,
                                                                                           dropArea.targetIndex);
                                                           ItemModel.changeSeparateIndex(true);
                                                       }
                                                   }
                                               }

                        onIsEmptyChanged: {
                            foldItem.visible = foldBase.isEmpty ? false : true;
                            foldWindow.hide();
                            trayview.isFold = false;
                        }
                    }

                    onVisibleChanged: {
                        dropArea.panelActive = foldWindow.visible;
                    }

                    onActiveFocusItemChanged: {
                        if (foldControl.pressed) return;
                        if (trayview.isFold) {
                            if (activeFocusItem === null) {
                                foldWindow.hide();
                                trayview.isFold = false;
                            }
                        }
                    }
                }
            }
        }

        ListView {
            id: trayview
            property string idSelect: ""
            property bool isFold: false
            property int sortIndex
            property int sourceIndex
            property real viewWidth: 0
            property int viewSpacing: 0
            height: dropArea.itemOrientation ? dropArea.itemHeight : viewWidth
            width: dropArea.itemOrientation ? viewWidth : dropArea.itemWidth
            orientation: dropArea.itemOrientation ? ListView.Horizontal : ListView.Vertical
            layoutDirection: ListView.RightToLeft
            verticalLayoutDirection: ListView.Qt.BottomToTop
            spacing: viewSpacing
            interactive: false

            Component.onCompleted: {
                var i = trayModel.count * dropArea.itemShort + (trayModel.count - 1) * trayview.viewSpacing;
                viewWidth = i;
            }

            displaced: Transition {
                ScriptAction {
                    script: {
                        trayview.viewWidth = trayModel.count * dropArea.itemShort + (trayModel.count - 1) * trayview.viewSpacing;
                    }
                }
                NumberAnimation { properties: "x,y"; easing.type: Easing.OutQuad; duration: 200 }
                NumberAnimation { properties: "z"; to: 1; easing.type: Easing.OutQuad; duration: 1 }
            }
            move: Transition {
                ScriptAction {
                    script: {
                        trayview.viewWidth = trayModel.count * dropArea.itemShort + (trayModel.count - 1) * trayview.viewSpacing;
                    }
                }
                NumberAnimation { properties: "x,y"; easing.type: Easing.OutQuad; duration: 200 }
                NumberAnimation { properties: "z"; to: 0; easing.type: Easing.OutQuad; duration: 1 }
            }
            model: DelegateModel {
                id: trayModel
                model: ShowModel

                groups: DelegateModelGroup {
                    name: "foldItems"
                    includeByDefault: false
                }
                delegate: Item {
                    id: showDropArea
                    property int visualIndex: DelegateModel.itemsIndex
                    property bool isFixed: model.Fixed === undefined ? false : model.Fixed
                    width: dropArea.itemWidth
                    height: dropArea.itemHeight
                    clip: true

                    ListView.onAdd: SequentialAnimation {
                        ScriptAction {
                            script: {
                                trayview.viewWidth = trayModel.count * dropArea.itemShort + (trayModel.count - 1) * trayview.viewSpacing;
                            }
                        }
                    }
                    ListView.onRemove: SequentialAnimation {
                        ScriptAction {
                            script: {
                                trayview.viewWidth = trayModel.count * dropArea.itemShort + (trayModel.count - 1) * trayview.viewSpacing;
                            }
                        }
                    }

                    Binding { target: control; property: "selectIndex"; value: visualIndex}
                    UkuiItems.StyleBackground {
                        id: controlBase
                        clip: true
                        useStyleTransparency: false
                        anchors.fill: parent
                        paletteRole: Platform.Theme.BrightText
                        alpha: control.pressed && control.isContain ? 0.1 : control.isContain ? 0.05 : 0

                        radius: Platform.Theme.maxRadius
                        TrayIcon {
                            id: control
                            property int selectIndex: 0
                            property bool isContain: false
                            property var rootId: dropArea
                            width: dropArea.itemWidth
                            height: dropArea.itemHeight
                            appStatus: model.Status === undefined ? "" : model.Status
                            appAttentionMovieName: model.AttentionMovieName === undefined ? "" : model.AttentionMovieName
                            appIcon: model.Icon
                            appAttentionIcon: model.AttentionIcon
                            appOverlayIcon: model.OverlayIcon

                            hoverEnabled: true
                            acceptedButtons: Qt.LeftButton | Qt.RightButton

                            Drag.active: drag.active
                            Drag.hotSpot.x: width / 2
                            Drag.hotSpot.y: height / 2
                            Drag.dragType: Drag.Automatic
                            Drag.onActiveChanged: {
                                if (Drag.active) {
                                    control.opacity = 0;
                                    exited();
                                }
                            }
                            UkuiItems.Tooltip {
                                id: tooltip
                                anchors.fill: parent
                                mainText: model.ToolTipTitle === undefined ? "" : model.ToolTipTitle.length === 0 ? model.Title : model.ToolTipTitle
                                posFollowCursor: false
                                location: {
                                    switch(dropArea.panelPos) {
                                        case UkuiItems.Types.Bottom:
                                            return UkuiItems.Dialog.BottomEdge;
                                        case UkuiItems.Types.Left:
                                            return UkuiItems.Dialog.LeftEdge;
                                        case UkuiItems.Types.Top:
                                            return UkuiItems.Dialog.TopEdge;
                                        case UkuiItems.Types.Right:
                                            return UkuiItems.Dialog.RightEdge;
                                    }
                                }
                                margin: 6
                            }

                            onEntered: {
                                isContain = true;
                            }
                            onExited: {
                                isContain = false
                            }
                            onCanceled: {
                                isContain = false
                            }

                            onClicked: {
                                if (mouse.button === Qt.LeftButton) {
                                    trayModel.model.onActivate(trayModel.modelIndex(index));
                                }
                                if (mouse.button === Qt.RightButton) {
                                    trayModel.model.onContextMenu(trayModel.modelIndex(index));
                                    dropArea.callMenu = true;
                                }
                            }

                            onPressed: {
                                if (model.Fixed) return;
                                if (mouse.button === Qt.LeftButton) {
                                    x = control.mapToItem(trayview,0,0).x;
                                    y = control.mapToItem(trayview,0,0).y;
                                    drag.target = control;
                                    control.parent = trayview;
                                    control.grabToImage(function(result) {
                                        control.Drag.imageSource = result.url;
                                    })
                                    trayview.sourceIndex = selectIndex;
                                    dropArea.dragType = 0;
                                }
                            }
                            onReleased: {
                                Drag.drop();
                                drag.target = null;
                                control.parent = controlBase;
                                control.opacity = 1
                                x = 0;
                                y = 0;
                            }
                            Drag.onDragFinished: {
                                foldItem.visible = !foldBase.isEmpty;
                                dropArea.panelActive = false;
                                if (dropArea.dragType === 0) {
                                    if (trayview.itemAtIndex(visualIndex).isFixed) return;
                                    ItemModel.setOrderInGroup(ShowModel, ShowModel.index(trayview.sourceIndex, 0), visualIndex);
                                }
                            }
                        }
                    }
                }
                onCountChanged: {
                    trayview.viewWidth = trayModel.count * dropArea.itemShort + (trayModel.count - 1) * trayview.viewSpacing;
                }
            }
        }
    }

    function changeFoldWindowPosition() {
        if (foldWindow.visible) {
            foldWindow.updatePosition();
        }
    }

    onPositionChanged: drag => {
                           if (drag.source.rootId !== dropArea) return;
                           if (!foldItem.visible) foldItem.visible = true;
                           dropArea.panelActive = true;
                           var target = getTarget(drag.x, drag.y);
                           if (target === -1) return;
                           if (dropArea.dragType === 0) {
                               if (trayview.itemAtIndex(target).isFixed) return;
                               trayModel.items.move(drag.source.selectIndex, target);
                           } else if (dropArea.dragType === 1) {
                               if (trayview.itemAtIndex(target).isFixed) return;
                               dropArea.targetIndex = target;
                               if (dropArea.inserted) {
                                   var i = target
                                   trayModel.items.move(drag.source.selectIndex, target)
                                   drag.source.selectIndex = i
                               } else {
                                   dropArea.inserted = true;
                                   if (trayModel.count > 11) {
                                       dropArea.isOverLength = true;
                                       ItemModel.changeSeparateIndex(false);
                                   } else {
                                       dropArea.isOverLength = false;
                                   }
                                   dropArea.indexInFold = drag.source.selectIndex;
                                   drag.source.selectIndex = target;
                                   trayModel.items.insert(target, {});
                               }
                           }
                       }
    onExited: {
        if (dropArea.inserted) {
            if (dropArea.isOverLength) {
                ItemModel.changeSeparateIndex(true);
            }
            trayModel.items.remove(dropArea.targetIndex);
            dropArea.inserted = false;
            drag.source.selectIndex = dropArea.indexInFold;
        }
    }

    function getTarget(x, y) {
        switch (dropArea.panelPos) {
        case UkuiItems.Types.Left:
            return trayview.indexAt(x, y - trayview.height - trayview.y);
        case UkuiItems.Types.Top:
            return trayview.indexAt((x - trayview.width - trayview.x), y);
        case UkuiItems.Types.Right:
            return trayview.indexAt(x, y - trayview.height - trayview.y);
        case UkuiItems.Types.Bottom:
            return trayview.indexAt((x - trayview.width - trayview.x), y);
        default:
            return -1;
        }
    }

    function menuStateChange(state) {
        if (dropArea.callMenu) {
            dropArea.panelActive = state;
            dropArea.callMenu = state;
        }
    }

    Component.onCompleted: {
        ItemModel.menuStateChanged.connect(menuStateChange);
    }
    Component.onDestruction: {
        ItemModel.menuStateChanged.disconnect(menuStateChange);
    }
}
